package nl.hu.verbrandendephoenix.controller;

import java.util.ArrayList;

import nl.hu.verbrandendephoenix.client.AppManager;
import nl.hu.verbrandendephoenix.client.NotificationManager;
import nl.hu.verbrandendephoenix.shared.Auction;
import nl.hu.verbrandendephoenix.shared.Bid;
import nl.hu.verbrandendephoenix.shared.FieldVerifier;
import nl.hu.verbrandendephoenix.shared.User;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;

public class ViewAuction {

	private nl.hu.verbrandendephoenix.view.ViewAuction viewAuction;
	private nl.hu.verbrandendephoenix.controller.BidStats bidStatsView;
	private int acID = 0, loggedUser = 0, lastBidUser = 0, auctionOwner = 0;
	private double minOffer = 0;
	private Auction currentAuction;

	public ViewAuction() { }

	public Panel getPanel(int auctionID) {
		acID = auctionID;
		viewAuction = new nl.hu.verbrandendephoenix.view.ViewAuction();
		Panel p = viewAuction.constructForm();
		isActive();
		getData();
		addHandlers();
		isCreator();
		isAdmin();
		return p;
	}

	@SuppressWarnings("deprecation")
	private void setAuctionData(Auction a) {
		minOffer = a.getIniPrice();
		auctionOwner = a.getUserID();
		viewAuction.setLblAuctionName(new Label(a.getAuctionName()));
		viewAuction.setLblDescription(new Label("Omschrijving: " + a.getDescription()));
		viewAuction.setLblPrice(new Label("Minimumbod: " + (int)a.getIniPrice() + " credits"));
		viewAuction.setLblCategory(new Label("Categorie: " + a.getCategory()));
		AppManager.get().getRpcService().getUserFromID(a.getUserID(), new AsyncCallback<User>() {
			public void onFailure(Throwable caught) {
				caught.getMessage();
			}

			public void onSuccess(User result) {
				viewAuction.setLblOwner(new Label(result.getUserName()));
			}
		});
		viewAuction.setLblStartDate(new Label("Aanmaakdatum: " + a.getEndDate()));
		a.getEndDate().setMonth(a.getEndDate().getMonth() + 1);
		viewAuction.setLblEndDate(new Label("Einddatum: " + a.getEndDate()));
	}

	private void setBidData(Bid b) {
		lastBidUser = b.getUserID();
		if(b.getPrice() == 0)
			viewAuction.setLblCurrentOffer(new Label("Huidige bod: geen"));
		else
			viewAuction.setLblCurrentOffer(new Label("Huidige bod: " + (int)b.getPrice() + " credits"));
		if(b.getUserID() == 0)
			viewAuction.setLblOfferBy(new Label("Uitgebracht door: niemand"));
		else {
			AppManager.get().getRpcService().getUserFromID(b.getUserID(), new AsyncCallback<User>() {
				public void onFailure(Throwable caught) {
					caught.getMessage();
				}

				public void onSuccess(User result) {
					viewAuction.setLblOfferBy(new Label("Uitgebracht door: " + result.getUserName()));
				}	
			});
		}
		if(b.getDate() == null)
			viewAuction.setLblOfferDate(new Label("Op datum: geen"));
		else
			viewAuction.setLblOfferDate(new Label("Op datum: " + b.getDate()));
	}

	public void getData() {
		final NotificationManager nM = NotificationManager.get();

		AppManager.get().getRpcService().getUserID(Cookies.getCookie("loginString"), new AsyncCallback<Integer>() {

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();
			}

			@Override
			public void onSuccess(Integer result) {
				loggedUser = result;
			}

		});

		AppManager.get().getRpcService().getAuctionData(acID, new AsyncCallback<Auction>() {
			public void onFailure(Throwable caught) {
				nM.commError();
			}
			public void onSuccess(Auction result) {
				if(result != null) {
					currentAuction = result;
					setAuctionData(result);
					AppManager.get().getRpcService().getLatestOffer(acID, new AsyncCallback<Bid>() {
						public void onFailure(Throwable caught) {
							nM.commError();
						}
						public void onSuccess(Bid result) {
							if(result != null) {
								setBidData(result);
							} else {
								nM.createNotification("Veiling bestaat niet meer.");
							}
						}
					});
				} else {
					nM.createNotification("Veiling bestaat niet meer.");
				}
			}
		});
	}

	public void isCreator(){
		AppManager.get().getRpcService().compareAuctionOwner(acID, Cookies.getCookie("loginString"), new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();

			}

			@Override
			public void onSuccess(Boolean result) {
				if(result){			

					viewAuction.btnEdit.setVisible(true);
					viewAuction.btnClose.setVisible(true);
					viewAuction.btnSale.setVisible(true);

				}

			}

		});

	}

	public void isAdmin(){
		AppManager.get().getRpcService().isAdmin(Cookies.getCookie("loginString"), new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();

			}

			@Override
			public void onSuccess(Boolean result) {
				if(result){			
					viewAuction.btnStats.setVisible(true);
					viewAuction.btnEdit.setVisible(true);
					viewAuction.btnClose.setVisible(true);
				}

			}

		});

	}

	public void isActive() {
		AppManager.get().getRpcService().checkActive(acID, new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();
			}

			@Override
			public void onSuccess(Boolean result) {
				if (!result) {
					closedAuction();
				}
			}
		});
	}

	public void closedAuction() {
		AppManager.get().getRpcService().getLatestOffer(acID, new AsyncCallback<Bid>() {
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();
			}
			public void onSuccess(final Bid b) {
				if(b != null) {
					AppManager.get().getRpcService().getUserData(b.getUserID(), new AsyncCallback<User>() {

						@Override
						public void onFailure(Throwable caught) {
							NotificationManager.get().commError();
						}

						@Override
						public void onSuccess(final User u) {
							AppManager.get().getRpcService().getAuctionData(acID, new AsyncCallback<Auction>() {

								@Override
								public void onFailure(Throwable caught) {
									NotificationManager.get().commError();
								}

								@Override
								public void onSuccess(Auction a) {
									viewAuction.closedAuction(u, b, a);
								}
							});
						}
					});
				} else {
					NotificationManager.get().createNotification("Ongeldige veiling");
				}
			}
		});

	}

	public void updateAuction(){
		final NotificationManager nM = NotificationManager.get();

		currentAuction.setDescription(viewAuction.txtDescription.getText());
		currentAuction.setCategory(viewAuction.category.getItemText(viewAuction.category.getSelectedIndex()));

		if(viewAuction.category.getItemText(viewAuction.category.getSelectedIndex()).length() > 2 && 
				viewAuction.txtDescription.getText().length() > 10){ 
			AppManager.get().getRpcService().editAuction(acID, currentAuction, new AsyncCallback<Boolean>(){

				@Override
				public void onFailure(Throwable caught) {
					NotificationManager.get().commError();
				}

				@Override
				public void onSuccess(Boolean result) {
					if(result){
						viewAuction.lblDescription.setText("Omschrijving: " + currentAuction.getDescription());
						viewAuction.lblCategory.setText("Categorie: " + currentAuction.getCategory());
						viewAuction.lblDescription.setVisible(true);
						viewAuction.lblCategory.setVisible(true);
						viewAuction.txtDescription.setEnabled(false);
						viewAuction.txtDescription.setVisible(false);
						viewAuction.category.setVisible(false);
						viewAuction.category.setEnabled(false);
						viewAuction.grdViewAuction.setWidget(1, 0, viewAuction.lblDescription);
						viewAuction.grdViewAuction.setWidget(3, 0, viewAuction.lblCategory);
						viewAuction.grdButtons.setWidget(1, 3, viewAuction.btnEdit);
						viewAuction.btnSave.setVisible(false);
						viewAuction.btnEdit.setVisible(true);

						nM.createNotification("Veiling succesvol bijgewerkt");

					}

				}

			});
		}else{
			nM.createNotification("U moet wel allebei de velden invullen!");
		}

	}

	public void closeAuction(){
		AppManager.get().getRpcService().deleteAuction(acID, new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();

			}

			@Override
			public void onSuccess(Boolean result) {
				if(result){
					NotificationManager.get().createNotification("Veiling succesvol verwijdert");
					History.newItem("myAuctions");
				}
			}
		});
	}

	public void sellAuction(){
		AppManager.get().getRpcService().payCredits(acID, Cookies.getCookie("loginString"), new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();

			}

			@Override
			public void onSuccess(Boolean result) {
				NotificationManager.get().createNotification("U heeft de veiling verkocht");
				stopAuction();


			}

		});


	}

	public void stopAuction(){
		AppManager.get().getRpcService().stopAuction(acID, new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();

			}

			@Override
			public void onSuccess(Boolean result) {
				isActive();


			}


		});
	}
	
	public void checkForBid(){
		AppManager.get().getRpcService().checkForBid(acID, new AsyncCallback<Boolean>(){

			@Override
			public void onFailure(Throwable caught) {
				NotificationManager.get().commError();
				
			}

			@Override
			public void onSuccess(Boolean result) {
				if(result == false){
				NotificationManager.get().createNotification("Er moet wel een bod gedaan zijn!");
				}else if(result == true){
					sellAuction();
				}
			}
			
		});
	}
	

	private void processSubmit() {
		final NotificationManager nM =  NotificationManager.get();

		if(checkFields()) {
			if(Double.parseDouble(viewAuction.getTxtOffer().getText()) >= minOffer) {
				if(auctionOwner != loggedUser) {
					if(loggedUser != lastBidUser) {
						if(loggedUser != 0 && loggedUser != -1) {
							AppManager.get().getRpcService().bidAuction(acID, Double.parseDouble(viewAuction.getTxtOffer().getText()), Cookies.getCookie("loginString"), new AsyncCallback<Boolean>() {

								public void onFailure(Throwable caught) {
									NotificationManager.get().commError();
								}

								public void onSuccess(Boolean result) {
									if(result) {
										nM.createNotification("Bod is succesvol opgeslagen");
										getData();
									} 
									else {
										nM.createNotification("Bod is lager dan de huidige bod!");
									}
								}
							});
						}
						else {
							nM.createNotification("Je bent niet ingelogd!");
							History.newItem("register");
						}
					}
					else {
						nM.createNotification("Je kunt niet bovenop je eigen bieding bieden!");
					}
				}
				else {
					nM.createNotification("Je kunt niet op je eigen veiling bieden!");
				}
			}
			else {
				nM.createNotification("Je bod is lager dan het minimale bod.");
			}
		}
		else {
			nM.createNotification("Er is iets mis gegaan!");
		}
	}

	private boolean checkFields() {
		FieldVerifier fv = FieldVerifier.get();
		boolean b = true; 

		TextBox txtOffer = viewAuction.getTxtOffer();
		if(!fv.checkDouble(txtOffer.getText())) {
			fv.addRequired(txtOffer);
			b = false;
		} else {
			fv.removeRequired(txtOffer);
		}

		return b;
	}

	public void addHandlers() {
		final NotificationManager nM =  NotificationManager.get();

		Button btnBid = viewAuction.getBtnBid();
		btnBid.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				processSubmit();
			} 
		});

		Button btnCancel = viewAuction.getBtnCancel();
		btnCancel.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				History.newItem("searchauction");
			} 
		});

		Button btnEdit = viewAuction.getBtnEdit();
		btnEdit.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){

				String blaat = currentAuction.getDescription();
				viewAuction.lblDescription.setVisible(false);
				viewAuction.lblCategory.setVisible(false);
				viewAuction.grdViewAuction.setWidget(1, 0, viewAuction.txtDescription);
				viewAuction.txtDescription.setEnabled(true);
				viewAuction.txtDescription.setVisible(true);
				viewAuction.txtDescription.setText(blaat);
				viewAuction.grdViewAuction.setWidget(3, 0, viewAuction.category);
				viewAuction.category.clear();
				viewAuction.category.addItem(null);
				viewAuction.category.addItem("Boeken");
				viewAuction.category.addItem("Drogist");
				viewAuction.category.addItem("Elektronica");
				viewAuction.category.addItem("Huishoudelijk");
				viewAuction.category.addItem("Meubilair");
				viewAuction.category.addItem("Multimedia");
				viewAuction.category.addItem("Voertuigen");
				viewAuction.category.setVisible(true);
				viewAuction.category.setEnabled(true);
				viewAuction.btnEdit.setVisible(false);
				viewAuction.btnSave.setVisible(true);
				viewAuction.grdButtons.setWidget(1, 3, viewAuction.btnSave);

			}
		});

		Button btnClose = viewAuction.getBtnClose();
		btnClose.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				closeAuction();
			}
		});

		Button btnSave = viewAuction.getBtnSave();
		btnSave.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event){
				updateAuction();
			}
		});

		Button btnRemove = viewAuction.getBtnRemove();
		btnRemove.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event){
				closeAuction();
			}
		});

		final Button btnStats = viewAuction.getBtnStats();
		btnStats.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				btnStats.setEnabled(false);
				AppManager.get().getRpcService().getAllBidsFromID(acID, new AsyncCallback<ArrayList<Bid>>() {

					public void onFailure(Throwable caught) {
						NotificationManager.get().commError();
					}

					public void onSuccess(ArrayList<Bid> result) {
						if (result != null) {
							bidStatsView = new nl.hu.verbrandendephoenix.controller.BidStats();
							viewAuction.getPnlViewAuction().add(bidStatsView.getPanel(acID));
						}
						else
							nM.createNotification("Er zijn nog geen biedingen!");
					} 
				});
			}

		});

		Button btnSale = viewAuction.getBtnSale();
		btnSale.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				
				checkForBid();
				
			}

		});

		ArrayList<TextBox> arrTextBoxes = viewAuction.getArrTextBox();
		for(TextBox tb : arrTextBoxes) {
			tb.addKeyPressHandler(new KeyPressHandler() {
				@Override
				public void onKeyPress(KeyPressEvent event) {
					if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
						processSubmit();
					}
				}
			});
		}
	}
}
